package cn.com.connext.scrm.service;

import cn.com.connext.scrm.domain.enumeration.AuditStatus;
import cn.com.connext.scrm.domain.enumeration.DeleteStatus;
import cn.com.connext.scrm.domain.master.*;
import cn.com.connext.scrm.repository.master.*;
import cn.com.connext.scrm.service.dto.JsonResult;
import cn.com.connext.scrm.service.mapper.ActivitiesService;
import cn.com.connext.scrm.utils.EntityUtils;
import cn.com.connext.scrm.utils.RedisUtils;
import cn.com.connext.scrm.web.rest.errors.MyErrorCode;
import cn.com.connext.scrm.web.rest.req.*;
import cn.com.connext.scrm.web.rest.resp.*;
import cn.com.connext.scrm.web.rest.vm.QueryIdVM;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.connext.common.exception.ServiceException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.*;

@Service
public class ActivitiesServiceImpl implements ActivitiesService {
    private final Logger log = LoggerFactory.getLogger(ActivitiesServiceImpl.class);

    @Autowired
    private ActivityRepository activityRepository;

    @Autowired
    private AuditForActivityRepository auditForActivityRepository;

    @Autowired
    private AwardRecordRepository awardRecordRepository;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private TeacherRepository teacherRepository;

    @Autowired
    private DWAUserInfoRepository dwaUserInfoRepository;

    @Autowired
    private AnswerTypeRepository answerTypeRepository;

    @Autowired
    private NoteCollectionRepository noteCollectionRepository;

    @Autowired
    private NoteLikesRepository noteLikesRepository;

    @Autowired
    private CommentRepository commentRepository;

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private NoteRepository noteRepository;

    @Autowired
    private WhiskeyGiftsRepository whiskeyGiftsRepository;

    @Autowired
    private BrowseRecordActivityRepository BrowseRecordActivityRepository;

    private final static Object REDIS_LOCK3 = new Object();

    @Transactional
    @Override
    public ResponseEntity<Boolean> create(ActivityCreateReq req) {
        Activity activity = new Activity();
        BeanUtils.copyProperties(req, activity);
        activity.setIsAnswer(true);
        activity.setEnableFlag(false);
        activity.setAuditResult(0);
        activity.setCreateTime(new Date());
        activity.setUpdateTime(new Date());
        activity.setIsDelete(0);
        //TODO activityPage
        activity.setActivityPage("无");
        activityRepository.saveAndFlush(activity);
        return ResponseEntity.ok(true);
    }

    @Override
    public ResponseEntity<Boolean> update(ActivityUpdateReq req) {
        Activity activity = activityRepository.findOne(req.getId());
        BeanUtils.copyProperties(req, activity);
        activity.setIsAnswer(true);
        activity.setAuditResult(0);
        activity.setUpdateTime(new Date());
        activityRepository.saveAndFlush(activity);
        return ResponseEntity.ok(true);
    }

    @Override
    public ResponseEntity audit(ActivityAuditReq req) {
        Activity activity = activityRepository.findOne(req.getId());
        if (null == activity) {
            return ResponseEntity.ok(false);
        }
        //保存问答表
        activity.setAuditResult(req.getAuditResult());
        activity.setEnableFlag(req.getAuditResult() == 1 ? true : false);//0初始状态  1审核通过  2 审核未通过
        activityRepository.saveAndFlush(activity);
        //保存审批记录
        AuditForActivity auditForActivity = new AuditForActivity();
        auditForActivity.setActivityId(req.getId());
        auditForActivity.setAuditResult(req.getAuditResult());
        auditForActivity.setCreateTime(new Date());
        auditForActivity.setRemark(StringUtils.isBlank(req.getRemark()) ? new String("null") : req.getRemark());
        auditForActivityRepository.saveAndFlush(auditForActivity);
        return ResponseEntity.ok(true);
    }

    @Override
    public ResponseEntity<Page<QueryActivitiesResp>> queryActivities(ActivityQueryReq req) {
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.DESC, "createTime"));
        Specification<Activity> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(req.getContent())) {
                list.add(criteriaBuilder.like(root.get("content"), "%" + req.getContent() + "%"));
            }
            if (StringUtils.isNotEmpty(req.getActivityName())) {
                list.add(criteriaBuilder.like(root.get("activityName"), "%" + req.getActivityName() + "%"));
            }
            if (StringUtils.isNotEmpty(req.getDescription())) {
                list.add(criteriaBuilder.like(root.get("description"), "%" + req.getDescription() + "%"));
            }
            if (null != req.getAuditResult()) {
                list.add(criteriaBuilder.equal(root.get("auditResult"), req.getAuditResult()));
            }
            list.add(criteriaBuilder.equal(root.get("isAnswer"), 1));//问答
            list.add(criteriaBuilder.equal(root.get("isDelete"), 0));//未删除
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<Activity> page = activityRepository.findAll(specification, pageable);
        List<Activity> content = page.getContent();
        if (CollectionUtils.isEmpty(content)) {
            PageImpl<QueryActivitiesResp> pageTasks = new PageImpl<>(Collections.emptyList(), pageable, page.getTotalElements());
            return ResponseEntity.ok(pageTasks);
        }
        List<QueryActivitiesResp> queryActivitiesResps = EntityUtils.dtoList2PojoList(content, QueryActivitiesResp.class);
        return ResponseEntity.ok(new PageImpl<>(queryActivitiesResps, pageable, page.getTotalElements()));
    }

    @Override
    public ResponseEntity<QueryActivitiesResp> detail(ActivityDetailReq req) {
        QueryActivitiesResp queryActivitiesResp = new QueryActivitiesResp();
        Activity activity = activityRepository.findOne(req.getId());
        if (null == activity) {
            return ResponseEntity.ok(null);
        }
        if (StringUtils.isNotBlank(activity.getGiftId())) {
            WhiskeyGifts whiskeyGifts = whiskeyGiftsRepository.findOne(activity.getGiftId());
            queryActivitiesResp.setGiftName(whiskeyGifts.getName());
        }
        //查询是否可以设置中奖人
        Activity activityNew = activityRepository.getPostActivityForAnswer();
        if (null == activityNew) {
            queryActivitiesResp.setWinner(false);
        } else {
            queryActivitiesResp.setWinner(activityNew.getId().compareTo(req.getId()) == 0 ? true : false);
        }
        BeanUtils.copyProperties(activity, queryActivitiesResp);
        return ResponseEntity.ok(queryActivitiesResp);
    }

    @Override
    public ResponseEntity<QueryNowAndPostActivitiesResp> queryAnswerNowActivities() {
        QueryNowAndPostActivitiesResp queryNowAndPostActivitiesResp = new QueryNowAndPostActivitiesResp();
        List<Activity> activityList = activityRepository.getCurrentActivityForAnswer();
        if (CollectionUtils.isEmpty(activityList)) {
            return ResponseEntity.ok(queryNowAndPostActivitiesResp);
        }
        BeanUtils.copyProperties(activityList.get(0), queryNowAndPostActivitiesResp);
        //礼物
        List<WhiskeyGifts> whiskeyGifts = whiskeyGiftsRepository.findByActivityId(activityList.get(0).getId());
        if (CollectionUtils.isNotEmpty(whiskeyGifts)) {
            List<WhiskeyGiftsResp> whiskeyGiftsResps = EntityUtils.dtoList2PojoList(whiskeyGifts, WhiskeyGiftsResp.class);
            queryNowAndPostActivitiesResp.setWhiskeyGiftsResp(whiskeyGiftsResps.get(0));
        }
        //中奖人
        List<AwardRecord> awardRecords = awardRecordRepository.findByActivityId(activityList.get(0).getId());
        if (CollectionUtils.isNotEmpty(awardRecords)) {
            WhiskeyAwardsResp whiskeyAwardsResp = new WhiskeyAwardsResp();
            AwardRecord awardRecord = awardRecords.get(0);
            whiskeyAwardsResp.setAwardContent(awardRecord.getAwardContent());
            whiskeyAwardsResp.setUnionId(awardRecord.getUnionId());
            Member member = memberRepository.findOneByUnionId(awardRecord.getUnionId());
            if (null != member) {
                whiskeyAwardsResp.setAccount(member.getAccount());
            }
            queryNowAndPostActivitiesResp.setWhiskeyAwardsResp(whiskeyAwardsResp);
        }
        //浏览量
        Integer count = BrowseRecordActivityRepository.countAllByActId(activityList.get(0).getId());
        queryNowAndPostActivitiesResp.setBrowseRecordCount(null == count ? new Integer(0) : count);
        return ResponseEntity.ok(queryNowAndPostActivitiesResp);
    }

    @Override
    public ResponseEntity<List<QueryNowAndPostActivitiesResp>> queryAnswerPostActivities() {
        List<Activity> activityList = activityRepository.getPostActivityForAnswers();
        if (CollectionUtils.isEmpty(activityList)) {
            return ResponseEntity.ok(Collections.emptyList());
        }
        List<QueryNowAndPostActivitiesResp> queryNowAndPostActivitiesResps = EntityUtils.dtoList2PojoList(activityList, QueryNowAndPostActivitiesResp.class);
        //礼物
        queryNowAndPostActivitiesResps.forEach(c -> {
            List<WhiskeyGifts> whiskeyGifts = whiskeyGiftsRepository.findByActivityId(c.getId());
            if (CollectionUtils.isNotEmpty(whiskeyGifts)) {
                List<WhiskeyGiftsResp> whiskeyGiftsResps = EntityUtils.dtoList2PojoList(whiskeyGifts, WhiskeyGiftsResp.class);
                c.setWhiskeyGiftsResp(whiskeyGiftsResps.get(0));
            }
            //中奖人
            List<AwardRecord> awardRecords = awardRecordRepository.findByActivityId(c.getId());
            if (CollectionUtils.isNotEmpty(awardRecords)) {
                WhiskeyAwardsResp whiskeyAwardsResp = new WhiskeyAwardsResp();
                AwardRecord awardRecord = awardRecords.get(0);
                whiskeyAwardsResp.setAwardContent(awardRecord.getAwardContent());
                whiskeyAwardsResp.setUnionId(awardRecord.getUnionId());
                Member member = memberRepository.findOneByUnionId(awardRecord.getUnionId());
                if (null != member) {
                    whiskeyAwardsResp.setAccount(member.getAccount());
                }
                c.setWhiskeyAwardsResp(whiskeyAwardsResp);
            }
        });
        return ResponseEntity.ok(queryNowAndPostActivitiesResps);
    }

    @Override
    public JsonResult answerenable(QueryIdVM req) {
        JsonResult result = new JsonResult();
        Activity activity = activityRepository.findOne(req.getId());
        if (activity == null) {
            throw new ServiceException(MyErrorCode.ERROR_DATA_ISNULL);
        }
        if (activity.isEnableFlag()) {
            activity.setEnableFlag(false);
        } else {
            //特殊活动只能一个启用
            List<Activity> activityList = activityRepository.getCurrentActivityForAnswer();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(activityList)) {
                result.setMessage("当期已经有启用活动，无法启用");
                result.setState(0);
                return result;
            }
            activity.setEnableFlag(true);
        }
        result.setMessage("操作成功");
        result.setState(0);
        activityRepository.saveAndFlush(activity);
        return result;
    }

    @Override
    public ResponseEntity<Page> queryAnswerNowNotes(PageBaseReq req) {
        //分页查询
        List<Activity> activityList = activityRepository.getCurrentActivityForAnswer();
        if (CollectionUtils.isEmpty(activityList)) {
            return ResponseEntity.ok(null);
        }
        Activity activity = activityList.get(0);
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.DESC, "createTime"));//分页 排序
        Specification<Note> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.between(root.get("createTime"), activity.getStartTime(), activity.getEndTime()));
            list.add(criteriaBuilder.equal(root.get("deleteStatus"), DeleteStatus.ACTIVATED));
            list.add(criteriaBuilder.equal(root.get("auditStatus"), AuditStatus.AUDITED));
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<Note> page = noteRepository.findAll(specification, pageable);
        List<Note> content = page.getContent();
        if (CollectionUtils.isEmpty(content)) {
            PageImpl<AnswerType> pageTasks = new PageImpl<>(Collections.emptyList(), pageable, page.getTotalElements());
            return ResponseEntity.ok(pageTasks);
        }
        List<QueryAnswerDetailResp> queryAnswerDetailResps = new ArrayList<>();
        content.forEach(c -> {
            QueryAnswerDetailResp queryAnswerDetailResp = cover(c);
            if (StringUtils.isNotBlank(c.getImgUrl())) {
                queryAnswerDetailResp.setImgUrlList(Arrays.asList(c.getImgUrl().split(",")));
            }
            queryAnswerDetailResps.add(queryAnswerDetailResp);
        });
        return ResponseEntity.ok(new PageImpl<>(queryAnswerDetailResps, pageable, page.getTotalElements()));
    }

    @Override
    public ResponseEntity<Page> queryAnswerPostNotes(QueryAnswerPostNotesReq req) {
        int currentPage = (req.getCurrentPage() - 1) < 0 ? 0 : req.getCurrentPage() - 1;
        int pageSize = req.getPageSize() < 1 ? 10 : req.getPageSize();
        Pageable pageable = new PageRequest(currentPage, pageSize, new Sort(Sort.Direction.DESC, "createTime"));//分页 排序
        //分页查询  帖子信息
        Activity activity = activityRepository.findOne(req.getActId());
        if (null == activity) {
            return ResponseEntity.ok((new PageImpl<>(Collections.emptyList(), pageable, 0)));
        }
        Specification<Note> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.between(root.get("createTime"), activity.getStartTime(), activity.getEndTime()));
            list.add(criteriaBuilder.equal(root.get("deleteStatus"), DeleteStatus.ACTIVATED));
            list.add(criteriaBuilder.equal(root.get("auditStatus"), AuditStatus.AUDITED));
            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };
        Page<Note> page = noteRepository.findAll(specification, pageable);
        List<Note> content = page.getContent();
        if (CollectionUtils.isEmpty(content)) {
            PageImpl<AnswerType> pageTasks = new PageImpl<>(Collections.emptyList(), pageable, page.getTotalElements());
            return ResponseEntity.ok(pageTasks);
        }
        List<QueryAnswerDetailResp> queryAnswerDetailResps = new ArrayList<>();
        //查询活动中奖纪录
        List<AwardRecord> awardRecord = awardRecordRepository.findByActivityId(req.getActId());
        content.forEach(c -> {
            QueryAnswerDetailResp queryAnswerDetailResp = cover(c);
            if (StringUtils.isNotBlank(c.getImgUrl())) {
                queryAnswerDetailResp.setImgUrlList(Arrays.asList(c.getImgUrl().split(",")));
            }
            if (CollectionUtils.isNotEmpty(awardRecord)) {
                if (awardRecord.get(0).getNoteId().compareTo(c.getId()) == 0) {
                    queryAnswerDetailResp.setOne(true);
                } else {
                    queryAnswerDetailResp.setOne(false);
                }
            }
            queryAnswerDetailResps.add(queryAnswerDetailResp);
        });
        return ResponseEntity.ok(new PageImpl<>(queryAnswerDetailResps, pageable, page.getTotalElements()));
    }

    @Override
    public ResponseEntity<QueryNowAndPostActivitiesResp> queryAnswerPostActivitiesDetail(String id) {
        QueryNowAndPostActivitiesResp queryNowAndPostActivitiesResp = new QueryNowAndPostActivitiesResp();
        Activity activity = activityRepository.findOne(id);
        if (null == activity) {
            return ResponseEntity.ok(queryNowAndPostActivitiesResp);
        }
        BeanUtils.copyProperties(activity, queryNowAndPostActivitiesResp);
        //礼物
        List<WhiskeyGifts> whiskeyGifts = whiskeyGiftsRepository.findByActivityId(id);
        if (CollectionUtils.isNotEmpty(whiskeyGifts)) {
            List<WhiskeyGiftsResp> whiskeyGiftsResps = EntityUtils.dtoList2PojoList(whiskeyGifts, WhiskeyGiftsResp.class);
            queryNowAndPostActivitiesResp.setWhiskeyGiftsResp(whiskeyGiftsResps.get(0));
        }
        //中奖人
        List<AwardRecord> awardRecords = awardRecordRepository.findByActivityId(id);
        if (CollectionUtils.isNotEmpty(awardRecords)) {
            WhiskeyAwardsResp whiskeyAwardsResp = new WhiskeyAwardsResp();
            AwardRecord awardRecord = awardRecords.get(0);
            whiskeyAwardsResp.setAwardContent(awardRecord.getAwardContent());
            whiskeyAwardsResp.setUnionId(awardRecord.getUnionId());
            Member member = memberRepository.findOneByUnionId(awardRecord.getUnionId());
            if (null != member) {
                whiskeyAwardsResp.setAccount(member.getAccount());
            }
            queryNowAndPostActivitiesResp.setWhiskeyAwardsResp(whiskeyAwardsResp);
        }
        //浏览量
        Integer count = BrowseRecordActivityRepository.countAllByActId(id);
        queryNowAndPostActivitiesResp.setBrowseRecordCount(null == count ? new Integer(0) : count);
        return ResponseEntity.ok(queryNowAndPostActivitiesResp);
    }

    private QueryAnswerDetailResp cover(Note note) {
        QueryAnswerDetailResp queryAnswerDetailResp = new QueryAnswerDetailResp();
        String req = note.getId();
        BeanUtils.copyProperties(note, queryAnswerDetailResp);
        //发帖人昵称、头像、标签
        if (StringUtils.isNotEmpty(note.getUserId())) {
            Member member = memberRepository.findOneByUnionId(note.getUserId());
            if (null != member) {
                queryAnswerDetailResp.setNickName(member.getNickName());
                queryAnswerDetailResp.setHeadImgUrl(member.getHeadImgUrl());
                if (StringUtils.isNotEmpty(member.getMobile())) {
                    String mobile = member.getMobile();
                    JSONArray tagsArray = new JSONArray();
//                        tagsList.add("官方认证");
                    if (null != member.getOfficialCertification() && member.getOfficialCertification() == true) {
                        JSONObject tag = new JSONObject();
                        tag.put("kind", 2);
                        tag.put("text", "官方认证");
                        tagsArray.add(tag);
                    } else {
                        List<String> teacherMobiles = getTeacherMobileList();
                        if (teacherMobiles.contains(mobile)) {
//                        ///打上官方认证的标签
//                        tagsList.add("DWA老师");
                            JSONObject tag = new JSONObject();
                            tag.put("kind", 1);
                            tag.put("text", "DWA导师");
                            tagsArray.add(tag);
                        } else {
                            List<DwaUserInfo> dwaUserInfos = dwaUserInfoRepository.findByUnionIdOrderByLessonLevelDesc(note.getUserId());
                            if (null != dwaUserInfos && dwaUserInfos.size() > 0) {
                                //dwa学员标签
                                DwaUserInfo dwaUserInfo = dwaUserInfos.get(0);
                                if (org.apache.commons.lang3.StringUtils.isNotEmpty(dwaUserInfo.getLessonLevel())) {
                                    String level = dwaUserInfo.getLessonLevel();
                                    JSONObject tag = new JSONObject();
                                    tag.put("kind", 0);
                                    if ("LEVEL1".equals(level)) {
                                        tag.put("text", "DWA L1");
                                    } else if ("LEVEL2".equals(level)) {
                                        tag.put("text", "DWA L2");
                                    } else if ("LEVEL3".equals(level)) {
                                        tag.put("text", "DWA L3");
                                    } else {
                                        tag.put("text", "DWA");
                                    }
                                    tagsArray.add(tag);
                                }
                            }
                        }
                    }
                    queryAnswerDetailResp.setUserTagList(tagsArray);
                }
            }
        }
        //点赞数
        Integer totalLikes = 0;
        //评论数
        Integer totalComments = 0;
        //收藏数
        Integer totalCollection = 0;
        //浏览量
        Integer totalBrowseRecords = 0;
        totalLikes = noteLikesRepository.countAllByNoteId(req);
        totalComments = commentRepository.countAllByNoteId(req);
        totalCollection = noteCollectionRepository.countAllByNoteId(req);
        queryAnswerDetailResp.setTotalLikes(totalLikes);
        queryAnswerDetailResp.setTotalComments(totalComments);
        queryAnswerDetailResp.setTotalBrowseRecords(totalBrowseRecords);
        queryAnswerDetailResp.setTotalCollection(totalCollection);
        return queryAnswerDetailResp;
    }

    private List<String> getTeacherMobileList() {
        List<String> result = null;
        String redisKey = "TeacherMobileList";
        Object banners = redisUtils.get(redisKey);
        if (banners != null && banners instanceof List) {
            result = (List<String>) banners;
        }
        if (result == null) {
            synchronized (REDIS_LOCK3) {
                result = teacherRepository.findAllMobile();
                if (result == null) {
                    result = new ArrayList<>();
                }
                redisUtils.set(redisKey, result, 1200L);
            }
        }
        return result;
    }
}
